package com.ervanalb.cellradio.shared.communicator;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import com.ervanalb.cellradio.shared.communicator.packets.Packet;

/**
 * A special type of Listener which listens specifically for a single reply to a sent
 * message. This may be an ACK or a response. When it is created, it adds
 * itself to a Communicator's list of replyListeners. When it receives a reply,
 * it removes itself from this list. Calling getReply() blocks until a reply is
 * received. It is backed by a queue, so it may block without stalling the
 * Communicator. This class will be triggerred upon receipt of any packet type,
 * subclasses may implement a filter to discriminate between packets.
 * 
 * @see Communicator
 * @author eric
 */
public class ReplyListener implements PacketListener {

	protected BlockingQueue<Packet> queue;
	int message;
	public Communicator comm;

	public ReplyListener(Communicator comm, int message) {
		this.message = message;
		queue = new LinkedBlockingQueue<Packet>();
		this.comm = comm;
		comm.addReplyListener(this);
	}

	public Packet getReply(long timeout) {
		Packet p = null;
		try {
			p = queue.poll(timeout, TimeUnit.MILLISECONDS);
		} catch (InterruptedException e) {
		}
		suicide();
		return p;
	}

	public void suicide() {
		comm.delReplyListener(this);
	}

	public boolean filter(Packet p) {
		return true;
	}

	@Override
	public void processPacket(Packet p) {
		if (!filter(p))
			return;
		try {
			queue.put(p);
		} catch (InterruptedException e) {
		}
	}
}
